package cn.com.cifi.mars.schedled;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;

import org.apache.commons.collections.CollectionUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import cn.com.cifi.mars.bean.bo.SignActualCalculateBO;
import cn.com.cifi.mars.bean.bo.SignInitializeBO;
import cn.com.cifi.mars.bean.bo.SignPlanVersionDetailBO;
import cn.com.cifi.mars.bean.bo.SignProductCodeBO;
import cn.com.cifi.mars.bean.bo.SignSupplyDetailBO;
import cn.com.cifi.mars.bean.bo.SysLogBO;
import cn.com.cifi.mars.constant.Constants;
import cn.com.cifi.mars.constant.IsDeleteEnum;
import cn.com.cifi.mars.constant.IsSuccessEnum;
import cn.com.cifi.mars.constant.LogEventEnum;
import cn.com.cifi.mars.constant.LogSrcEnum;
import cn.com.cifi.mars.constant.LogTypeEnum;
import cn.com.cifi.mars.constant.OrgTypeEunm;
import cn.com.cifi.mars.constant.VersionTypeEunm;
import cn.com.cifi.mars.entity.SignPlanVersion;
import cn.com.cifi.mars.entity.SignPlanVersionDetail;
import cn.com.cifi.mars.entity.SignPlanVersionSupplyDetail;
import cn.com.cifi.mars.entity.SysJob;
import cn.com.cifi.mars.mapper.mars.DmDmPlanSignMonthMapper;
import cn.com.cifi.mars.mapper.mars.DmDmPlanSignYearMapper;
import cn.com.cifi.mars.mapper.mars.SignPlanVersionDetailMapper;
import cn.com.cifi.mars.mapper.mars.SignPlanVersionMapper;
import cn.com.cifi.mars.mapper.mars.SignPlanVersionSupplyDetailMapper;
import cn.com.cifi.mars.service.CommonService;
import cn.com.cifi.mars.service.DmDmPlanSignMonthService;
import cn.com.cifi.mars.service.SignPlanProgressService;
import cn.com.cifi.mars.service.SignPlanVersionService;
import cn.com.cifi.mars.service.SysJobService;
import cn.com.cifi.mars.service.SysLogService;
import cn.com.cifi.mars.util.LocalDateTimeUtils;
import cn.com.cifi.mars.util.UUIDUtils;
import cn.com.cifi.mars.util.WebUtils;

/**
 *
 * 类名称：SupplyPlanTasks
 * 类描述：签约计划定时任务
 * 创建人：jyx
 * 创建时间：2019年12月19日 下午8:05:00
 * @version 1.0.0
 */
@Component
public class SignPlanTasks {
	
	private static final Logger log = LoggerFactory.getLogger(SignPlanTasks.class);

    @Autowired
    private SignPlanVersionMapper signPlanVersionMapper;
    @Autowired
    private SignPlanVersionSupplyDetailMapper signPlanVersionSupplyDetailMapper;
    @Autowired
    private SignPlanVersionService signPlanVersionService;
    @Autowired
    private SignPlanVersionDetailMapper signPlanVersionDetailMapper;
    @Autowired
    private SysLogService sysLogService;
    @Autowired
    private SysJobService sysJobService;
    @Autowired
    private DmDmPlanSignMonthMapper dmDmPlanSignMonthMapper;
    @Autowired
    private DmDmPlanSignYearMapper dmDmPlanSignYearMapper;
    @Autowired
    private DmDmPlanSignMonthService dmDmPlanSignMonthService;
    @Autowired
    private SignPlanProgressService signPlanProgressService;
    @Autowired
    private CommonService commonService;

    /**
     * 刷新签约计划实际数据
     */
    @Scheduled(cron = "0 0 0/8 * * ?")
    public void SignActualTask(){
        boolean appointIP = commonService.isAppointIP();
        if (!appointIP){
            return;
        }
        SysJob job = sysJobService.selectJobByCode(Constants.ZERO_SEVEN);
        LocalDateTime start = null;
		LocalDateTime end = null;
        if(null!=job) {
            Integer jobId = job.getId();
			int count = sysJobService.lockJobById(jobId);
			LocalDateTime lastUpdateTime = job.getUpdateTime();
			boolean flag = LocalDateTimeUtils.isValidTime(lastUpdateTime, Constants.THREE);
			if (count == 1 && !flag) {
                try {
                	start  = LocalDateTime.now();
                    //版本所属时间
                    LocalDateTime time;
                    if(LocalDateTimeUtils.isBetween0And6()){
                        time = start.minusMonths(1L);
                    }else {
                        time = start;
                    }
                    String yearMonth = LocalDateTimeUtils.getLocalMonth(time);
                    //查询各分期下当前年月的最新动态版签约计划
                    List<SignPlanVersion> signPlanVersionList = signPlanVersionMapper.selectLatestVersionByVersionTypeAndAffiliationMonth(VersionTypeEunm.DYNAMIC.getKey(),yearMonth, IsDeleteEnum.NO.getKey());
                    //刷新指定版本实际签约数据
                    refreshSignData(signPlanVersionList,yearMonth);
                    saveLog("定时任务", "刷新当月实际签约数据", "刷新各分期下当前年月的最新动态版签约计划签约实际数据");
                    end = LocalDateTime.now();
                }catch(Exception e) {
                    log.error("###### errorMsg: ", e);
                    saveLog("定时任务", "刷新当月实际签约数据", e.toString());
                } finally {
                    sysJobService.resetJob(job,start,end);
                }
            }else {
            	sysJobService.resetStatus(job);
            }
        }
    }

    /**
     * 刷新指定版本实际签约数据
     * @param signPlanVersionList 版本集合
     * @param yearMonth
     */
    public void refreshSignData(List<SignPlanVersion> signPlanVersionList, String yearMonth){
        List<SignPlanVersionDetail> spvdList = new ArrayList<>();

        LocalDateTime now = LocalDateTime.now();
        LocalDateTime dateTime = LocalDateTimeUtils.toLocalDateTime(yearMonth);

        for (SignPlanVersion signPlanVersion:signPlanVersionList){
            String versionId = signPlanVersion.getId();
            String projectFid = signPlanVersion.getProjectfId();
            String versionType = signPlanVersion.getVersionType();
            String versionAttr = signPlanVersion.getVersionAttr();

            //签约计划详情模板
            SignPlanVersionDetail spvdTemplate = new SignPlanVersionDetail();
            spvdTemplate.setVersionId(versionId);
            spvdTemplate.setCreateBy(Constants.SYS);
            spvdTemplate.setCreateTime(LocalDateTime.now());

            // 查询版本下全部组团
            List<SignPlanVersionSupplyDetail> groupList = signPlanVersionSupplyDetailMapper.selectByType(versionId, OrgTypeEunm.ORG_GROUP.getKey(), IsDeleteEnum.NO.getKey());
            for (SignPlanVersionSupplyDetail group : groupList) {
                String pid = group.getSupplyPlanId();

                // 查询组团下产品构成组合列表
                List<SignProductCodeBO> signProductCodeBOs = signPlanVersionSupplyDetailMapper.selectProductCodes(versionId, pid, IsDeleteEnum.NO.getKey());
                for (SignProductCodeBO signSupplyProductCodeBO : signProductCodeBOs) {
                    // 初始化签约计划详情查询条件
                    signSupplyProductCodeBO.setVersionId(versionId);
                    signSupplyProductCodeBO.setPid(pid);
                    signSupplyProductCodeBO.setIsDel(IsDeleteEnum.NO.getKey());

                    // 查询组团下产品构成类型供货详情列表
                    List<SignPlanVersionSupplyDetail> supplyDetailList = signPlanVersionSupplyDetailMapper.selectSupplyPlanDetail(signSupplyProductCodeBO);
                    if (CollectionUtils.isEmpty(supplyDetailList)) {
                        continue;
                    }

                    //取签约供货详情,有实际取实际，无实际取计划
                    List<SignSupplyDetailBO> ssdBOList=signPlanVersionService.switchSignSupplyDetailBO(supplyDetailList);
                    //获取实际签约数据相关参数
                    SignActualCalculateBO signActualCalculateBO = signPlanVersionService.getSignActualCalculateBO(ssdBOList,versionAttr,projectFid);

                    SignPlanVersionSupplyDetail spvsd = supplyDetailList.get(0);
                    // 初始化签约计划详情共有数据模板
                    spvdTemplate = signPlanVersionService.initializeSignDetailTemplate(spvdTemplate,spvsd,group);
                    // 是否车位楼栋（0否,1是）
                    Integer isParking = spvsd.getIsParking();

                    SignPlanVersionDetail detail = new SignPlanVersionDetail();
                    try {
                        detail = spvdTemplate.clone();
                    } catch (CloneNotSupportedException e) {
                        log.error("###### errorMsg: ", e);
                    }
                    detail.setId(UUIDUtils.create()); // 主键
                    //是否历史月
                    boolean isBefore = LocalDateTimeUtils.compareDate(dateTime, now, 1);

                    List<SignSupplyDetailBO> monthSupplyDetailList = signPlanVersionService.getSignPlanVersionSupplyDetailBySuppluTime(ssdBOList, yearMonth);
                    // 签约计划时间默认当月1号(xxxx-xx-01)
                    detail.setSignPlanTime(LocalDateTimeUtils.toLocalDateTime(yearMonth));

                    //签约计划初始化参数
                    SignInitializeBO signInitializeBO = new SignInitializeBO();
                    signInitializeBO.setSignPlanVersionDetail(detail);
                    signInitializeBO.setSignSupplyDetailList(monthSupplyDetailList);
                    signInitializeBO.setIsParking(isParking);
                    signInitializeBO.setVersionType(versionType);
                    signInitializeBO.setYearMonth(yearMonth);
                    signInitializeBO.setIsBefore(isBefore);

                    //初始化签约实际数据
                    signPlanVersionService.initializeEarlySignDetail(signInitializeBO,signActualCalculateBO);
                    //查询当前产品构成签约详情
                    SignProductCodeBO signProductCodeBO=new SignProductCodeBO();
                    signProductCodeBO.setVersionId(versionId);
                    signProductCodeBO.setPid(group.getOrgId());
                    signProductCodeBO.setProductCode(signSupplyProductCodeBO.getProductCode());
                    signProductCodeBO.setBusinessType(signSupplyProductCodeBO.getBusinessType());
                    signProductCodeBO.setFreeType(signSupplyProductCodeBO.getFreeType());
                    signProductCodeBO.setProType(signSupplyProductCodeBO.getProType());
                    signProductCodeBO.setIsDel(IsDeleteEnum.NO.getKey());
                    signProductCodeBO.setTime(yearMonth);
                    SignPlanVersionDetail signPlanDetail = signPlanVersionDetailMapper.selectBySignPlanTime(signProductCodeBO);

                    if(null != signPlanDetail){
                        //存在差异则修改该产品构成签约详情
                        signPlanDetail.setYearEalySignRoomCountActual(detail.getYearEalySignRoomCountActual());
                        signPlanDetail.setYearEalySignRoomAreaActual(detail.getYearEalySignRoomAreaActual());
                        signPlanDetail.setYearEalySignAvgPriceActual(detail.getYearEalySignAvgPriceActual());
                        signPlanDetail.setYearEalySignSumPriceActual(detail.getYearEalySignSumPriceActual());
                        signPlanDetail.setEarlySignRoomCountActual(detail.getEarlySignRoomCountActual());
                        signPlanDetail.setEarlySignRoomAreaActual(detail.getEarlySignRoomAreaActual());
                        signPlanDetail.setEarlySignAvgPriceActual(detail.getEarlySignAvgPriceActual());
                        signPlanDetail.setEarlySignSumPriceActual(detail.getEarlySignSumPriceActual());
                        signPlanDetail.setSupplySignRoomCountActual(detail.getSupplySignRoomCountActual());
                        signPlanDetail.setSupplySignRoomAreaActual(detail.getSupplySignRoomAreaActual());
                        signPlanDetail.setSupplySignAvgPriceActual(detail.getSupplySignAvgPriceActual());
                        signPlanDetail.setSupplySignSumPriceActual(detail.getSupplySignSumPriceActual());
                        signPlanDetail.setUpdateBy(Constants.SYS.trim());
                        signPlanDetail.setUpdateTime(LocalDateTime.now());
                        spvdList.add(signPlanDetail);

                        signPlanVersionDetailMapper.updateById(signPlanDetail);
                    }else {
                        //查询产品构成组合最晚签约日期
                        LocalDateTime latest = signPlanVersionDetailMapper.selectLatestSignDateByProduct(signProductCodeBO);
                        // 记录月初存货
                        SignPlanVersionDetailBO spvdBO = new SignPlanVersionDetailBO();
                        spvdBO.initialize();

                        // 新增从原产品构成组合最晚签约日期到当前日期的签约数据,按月份初始化
                        for (LocalDateTime time = latest; LocalDateTimeUtils.compareDate(time, dateTime, 1); time = LocalDateTimeUtils.addDate(time)) {
                            SignPlanVersionDetail newSignDetail = new SignPlanVersionDetail();
                            try {
                                newSignDetail = spvdTemplate.clone();
                            } catch (CloneNotSupportedException e) {
                                log.error("###### errorMsg: ", e);
                            }
                            newSignDetail.setId(UUIDUtils.create()); // 主键
                            newSignDetail.setSignPlanTime(time);

                            newSignDetail.setEarlyRoomCount(spvdBO.getEarlyRoomCount());
                            newSignDetail.setEarlyRoomArea(spvdBO.getEarlyRoomArea());
                            newSignDetail.setEarlyAvgRoomArea(spvdBO.getEarlyAvgRoomArea());
                            newSignDetail.setEarlyAvgPrice(spvdBO.getEarlyAvgPrice());
                            newSignDetail.setEarlySumPrice(spvdBO.getEarlySumPrice());
                            newSignDetail.setEarlyCanSignRoomCount(newSignDetail.getEarlyRoomCount().subtract(newSignDetail.getEarlySignRoomCount()));

                            String signTime = LocalDateTimeUtils.formatTime(time, "yyyy-MM");
                            isBefore = LocalDateTimeUtils.compareDate(time, dateTime, 1);
                            monthSupplyDetailList = signPlanVersionService.getSignPlanVersionSupplyDetailBySuppluTime(ssdBOList, yearMonth);


                            //签约计划初始化参数
                            signInitializeBO = new SignInitializeBO();
                            signInitializeBO.setSignPlanVersionDetail(newSignDetail);
                            signInitializeBO.setSignSupplyDetailList(monthSupplyDetailList);
                            signInitializeBO.setIsParking(isParking);
                            signInitializeBO.setVersionType(versionType);
                            signInitializeBO.setYearMonth(signTime);
                            signInitializeBO.setIsBefore(isBefore);

                            //初始化签约实际数据
                            signPlanVersionService.initializeEarlySignDetail(signInitializeBO, signActualCalculateBO);
                            //计算下个月月初存货
                            signPlanVersionService.calculateMonthlyInventory(spvdBO, signInitializeBO);
                            signPlanVersionDetailMapper.insert(newSignDetail);
                        }
                    }
                }
            }
        }
    }

    /**
     * 刷新供销存综合分析表
     */
    @Scheduled(cron = "0 0 1/8 * * ?")
    public void dmAnalyticalTask(){
        boolean appointIP = commonService.isAppointIP();
        if (!appointIP){
            return;
        }
        SysJob job = sysJobService.selectJobByCode(Constants.ZERO_TWENTY_THREE);
        LocalDateTime start = null;
        LocalDateTime end = null;
        if(null!=job) {
        	Integer jobId = job.getId();
			int count = sysJobService.lockJobById(jobId);
			LocalDateTime lastUpdateTime = job.getUpdateTime();
			boolean flag = LocalDateTimeUtils.isValidTime(lastUpdateTime, Constants.THREE);
			if (count == 1 && !flag) {
                try {
                    start = LocalDateTime.now();
                    String yearMonth;
                    //若当前时间处于一号0点到6点之间
                    if (LocalDateTimeUtils.isBetween0And6()) {
                        yearMonth = LocalDateTimeUtils.getLocalMonth(LocalDateTime.now().minusMonths(1L));
                    } else {
                        yearMonth = LocalDateTimeUtils.getLocalMonth(LocalDateTime.now());
                    }
                    Integer yearMonthInt = Integer.valueOf(yearMonth.replace("-",""));

                    List<String> versionIdList = new ArrayList<>();
                    //查询全部项目
                    Set<String> projectIds = signPlanVersionService.selectProjectIdAll();
                    //查询每个项目指定年月全盘最新的版本集合
                    List<String> versionIds;
                    for(String projectId : projectIds){
                        dmDmPlanSignMonthMapper.delBySnapshootYearMonth(yearMonthInt);
                        dmDmPlanSignYearMapper.delBySnapshootYearMonth(yearMonthInt);
                        versionIds = signPlanVersionService.getOverallSignVersionList(projectId,yearMonth);
                        if(CollectionUtils.isNotEmpty(versionIds)){
                            versionIdList.addAll(versionIds);
                        }
                    }
                    //刷新项目数据
                    if(CollectionUtils.isNotEmpty(versionIdList)){
                        dmDmPlanSignMonthService.toSign(versionIdList,yearMonth);
                    }
                    saveLog("定时任务", "供销综合分析底表定时刷新", "供销综合分析底表定时刷新");
                    end = LocalDateTime.now();
                } catch (Exception e) {
                    log.error("###### errorMsg: ", e);
                    saveLog("定时任务", "供销综合分析底表定时刷新", e.toString());
                } finally {
                    sysJobService.resetJob(job, start, end);
                }
            }else {
            	sysJobService.resetStatus(job);
            }
        }
    }
    
    
    /**
     * 刷新签约进度表
     */
    @Scheduled(cron = "0 0 0/3 * * ?")
    public void signPlanProgressTask(){
        boolean appointIP = commonService.isAppointIP();
        if (!appointIP){
            return;
        }
        SysJob job = sysJobService.selectJobByCode(Constants.ZERO_TWENTY_FOUR);
        LocalDateTime start = null;
        LocalDateTime end = null;
        if(null!=job) {
            Integer jobId = job.getId();
            int count = sysJobService.lockJobById(jobId);
            LocalDateTime lastUpdateTime = job.getUpdateTime();
            boolean flag = LocalDateTimeUtils.isValidTime(lastUpdateTime, Constants.THREE);
            if (count == 1 && !flag) {
                try {
                    start  = LocalDateTime.now();
                    //版本所属时间
                    LocalDateTime time;
                    if(LocalDateTimeUtils.isBetween0And6()){
                        //定时任务在1号的0点-6点执行时，刷新上个月签约进度表
                        time = start.minusMonths(1L);
                        String yearMonth = LocalDateTimeUtils.getLocalMonth(time);
                        signPlanProgressService.refresh(yearMonth);
                    }
                    time = start;
                    String yearMonth = LocalDateTimeUtils.getLocalMonth(time);
                    signPlanProgressService.refresh(yearMonth);

                    saveLog("定时任务", "刷新签约进度表", "刷新签约进度表");
                    end = LocalDateTime.now();
                }catch(Exception e) {
                    log.error("###### errorMsg: ", e);
                    saveLog("定时任务", "刷新签约进度表", e.toString());
                } finally {
                    sysJobService.resetJob(job,start,end);
                }
            }else {
                sysJobService.resetStatus(job);
            }
        }
    }


    private boolean saveLog(String module,String title,String content) {
        SysLogBO bo = new SysLogBO();
        bo.setEvent(LogEventEnum.BROWSE);
        bo.setSource(LogSrcEnum.PC);
        String hostAddr = WebUtils.getLocalIP();
        bo.setIp(hostAddr);
        bo.setModule(module);
        bo.setTitle(title);
        bo.setContent(content);
        bo.setType(LogTypeEnum.ZERO.getKey());
        bo.setIsSuccess(IsSuccessEnum.SUCCESS.getKey());
        return sysLogService.add(bo,Constants.SYS);
    }

}

